package com.joinway.framework.core.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.support.AopUtils;

public final class AopHelper {

    public static Method getMethod(JoinPoint point) {
        Method method = null;
        Signature signature = point.getSignature();

        if (signature instanceof MethodSignature) {
            MethodSignature ms = (MethodSignature) point.getSignature();
            method = AopUtils.getMostSpecificMethod(ms.getMethod(), point.getTarget().getClass());
        }

        return method;
    }
    
    /**
     * 如果Annonatation在类和方法上都有，方法级的优先
     * @param point
     * @param clazz
     * @param checkClass
     * @return
     */
    public static<T extends Annotation> T getAnnotation(JoinPoint point, Class<T> clazz, boolean checkClass){
    	Method method = getMethod(point);
    	T ann = method.getAnnotation(clazz);
    	
    	if(checkClass && ann == null){
    		ann = point.getTarget().getClass().getAnnotation(clazz);
    	}
    	
    	return ann;
    }
    
	public static Object getInputArg(JoinPoint point, int index){
    	Object arg = null;
    	
    	Object[] args = point.getArgs();
    	if(ArrayUtils.isNotEmpty(args) && args.length > index){
    		arg = args[index];
//	    	for(Object o : args){
//	    		if(o != null && o.getClass() == type.getClass()){
//	    			arg = (T)o;
//	    			break;
//	    		}
//	    	}
    	}
    	
    	return arg;
    }
    
	public static<T> Object getAnnotatedParamValue(Class<T> annCls, Method method, Object...args){
		Annotation[][] anns = method.getParameterAnnotations();
		
		Object target = null;
		boolean found = false;
		
		if(anns != null && anns.length > 0){
			for(int i = 0; i < anns.length; i++){
				Annotation[] arr = anns[i];
				if(arr != null && arr.length > 0){
					for(int j = 0; j < arr.length; j++){
						if(arr[j].annotationType() == annCls){
							target = args[i];
							found = true;
							break;
						}
					}
				}
				
				if(found){
					break;
				}
			}
		}
		
		return target;
	}
	
	private AopHelper(){}
}
